package com.q3d.demo.svc.hello.mybatis.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import com.q3d.demo.common.lib.service.dto.CountResultDto;
import com.q3d.demo.common.lib.service.dto.IdExtDto;
import com.q3d.demo.common.lib.service.dto.IdExtListDto;
import com.q3d.demo.common.lib.service.dto.OpResultDto;
import com.q3d.demo.common.lib.service.dto.PageRequestDto;
import com.q3d.demo.common.lib.service.dto.StringDto;
import com.q3d.demo.common.lib.service.dto.UuidDto;
import com.q3d.demo.common.lib.service.dto.UuidListDto;
import com.q3d.demo.common.lib.service.exception.ServiceException;
import com.q3d.demo.common.lib.service.response.ResponseStatus;
import com.q3d.demo.api.hello.service.HelloWorldServiceInterface;
import com.q3d.demo.api.hello.dto.HelloWorldP1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1K1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1K2Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1ListDto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K1ListDto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K2Dto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K2ListDto;
import com.q3d.demo.svc.hello.fsguid.manager.FsgUidManager;
import com.q3d.demo.svc.hello.mybatis.mapperext.HelloWorldModelMapperExt;
import com.q3d.demo.svc.hello.mybatis.model.HelloWorldModel;
import com.q3d.demo.svc.hello.mybatis.model.HelloWorldModelExample;
import com.q3d.demo.svc.hello.mybatis.model.HelloWorldModelExample.Criteria;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j /** Lombok 的 Logger 注解 */
@Validated /** Controller 中某些接口的入参可能没有封装 DTO 进行校验，因此在 Service 层再做一次校验 */
/**
 * @author 叶湘 ( weixin:yexiang841, email:yexiang841@qq.com )
 */
public class HelloWorldServiceBatis implements HelloWorldServiceInterface {

    @Autowired
    private HelloWorldModelMapperExt helloWorldModelMapper;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private FsgUidManager fsgUidManager;

    @Override
    public StringDto hello(@Valid StringDto dtoStringRequest) {
        StringDto dtoStringResponse = StringDto.builder().text(">>>> Hello " + dtoStringRequest.getText() + " <<<<")
                .build();
        return dtoStringResponse;
    }

    @Override
    public UuidDto addOne(@Valid HelloWorldP1Dto dtoP1) {
        HelloWorldModel model = null;
        try {
            // 使用 ModelMapper 工具将 DTO 转换成 Model
            model = modelMapper.map(dtoP1, HelloWorldModel.class);
            // 分布式生成全局统一 UID
            Long uid = fsgUidManager.getUid();
            model.setId(uid);
            // 执行数据库写操作
            int opResult = helloWorldModelMapper.insert(model);
            log.debug("addOne_dto: " + dtoP1.toString() + " opResult: " + opResult + " model: " + model);
        } catch (DataIntegrityViolationException e) {
            log.warn(e.getMessage());
            throw new ServiceException(ResponseStatus.BAD_REQUEST_PARAM_DATA_ERROR, e.getCause().getMessage());
        }
        // 组装 DTO 响应结构体
        UuidDto dtoUuid = UuidDto.builder().uuid(model.getUuid()).build();
        return dtoUuid;
    }

    @Override
    public UuidListDto addBatch(@Valid HelloWorldP1ListDto dtoP1List) {
        // 组装 List
        List<HelloWorldModel> modelList = new ArrayList<HelloWorldModel>(dtoP1List.getDtoList().size());
        for (HelloWorldP1Dto dtoP1 : dtoP1List.getDtoList()) {
            try {
                // 使用 ModelMapper 工具将 DTO 转换成 Model
                HelloWorldModel model = modelMapper.map(dtoP1, HelloWorldModel.class);
                modelList.add(model);
                // 分布式生成全局统一 UID
                Long uid = fsgUidManager.getUid();
                model.setId(uid);
            } catch (DataIntegrityViolationException e) {
                log.warn(e.getMessage());
                // 只要有一个参数不对，就会抛出异常，不会写入任何一个
                throw new ServiceException(ResponseStatus.BAD_REQUEST_PARAM_DATA_ERROR, e.getCause().getMessage());
            }
        }
        // 组装 DTO 响应结构体
        UuidListDto dtoUuidList = UuidListDto.builder().dtoList(new ArrayList<UuidDto>()).build();
        for (HelloWorldModel model : modelList) {
            try {
                // 执行数据库写操作
                int opResult = helloWorldModelMapper.insertSelective(model);
                if (opResult == 1) {
                    UuidDto dtoUuid = UuidDto.builder().uuid(model.getUuid()).build();
                    dtoUuidList.getDtoList().add(dtoUuid);
                }
                log.debug("addBatch_model: " + model.toString() + " opResult: " + opResult);
            } catch (DataIntegrityViolationException e) {
                // 这里不再抛出异常，成功一个算一个，不成功的跳过
                log.warn(e.getMessage());
            }
        }
        return dtoUuidList;
    }

    @Override
    public OpResultDto removeOne(@Valid UuidDto dtoUuid) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModel model = new HelloWorldModel();
        model.setActive((short) 0);
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andUuidEqualTo(dtoUuid.getUuid()).andActiveEqualTo((short) 1);
        // 执行数据库写操作，只修改标志位
        int opResult = helloWorldModelMapper.updateByExampleSelective(model, example);
        log.debug("removeOne_by_uuid: " + dtoUuid.getUuid() + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto removeBatch(@Valid UuidListDto dtoUuidList) {
        // 组装 List
        List<String> uuidList = new ArrayList<String>(dtoUuidList.getDtoList().size());
        for (UuidDto dtoUuid : dtoUuidList.getDtoList()) {
            uuidList.add(dtoUuid.getUuid());
        }
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModel model = new HelloWorldModel();
        model.setActive((short) 0);
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andUuidIn(uuidList).andActiveEqualTo((short) 1);
        // 执行数据库写操作，只修改标志位
        int opResult = helloWorldModelMapper.updateByExampleSelective(model, example);
        log.debug("removeBatch_by_uuid_list: " + uuidList + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto deleteOne(@Valid IdExtDto dtoIdExt) {
        Long id = Long.parseLong(dtoIdExt.getIdExt());
        // 执行数据库写操作，按 ID 删除
        int opResult = helloWorldModelMapper.deleteByPrimaryKey(id);
        log.debug("deleteOne_by_id: " + id + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto deleteBatch(@Valid IdExtListDto dtoIdExtList) {
        // 组装 List
        List<Long> idList = new ArrayList<Long>(dtoIdExtList.getDtoList().size());
        for (IdExtDto dtoIdExt : dtoIdExtList.getDtoList()) {
            idList.add(Long.parseLong(dtoIdExt.getIdExt()));
        }
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andIdIn(idList);
        // 执行数据库写操作，按 ID 列表删除
        int opResult = helloWorldModelMapper.deleteByExample(example);
        log.debug("deleteBatch_by_id_list: " + idList + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto reviveOne(@Valid IdExtDto dtoIdExt) {
        Long id = Long.parseLong(dtoIdExt.getIdExt());
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModel model = new HelloWorldModel();
        model.setId(id);
        model.setActive((short) 1);
        // 执行数据库写操作，按 ID 删除
        int opResult = helloWorldModelMapper.updateByPrimaryKeySelective(model);
        log.debug("reviveOne_by_id: " + id + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto reviveBatch(@Valid IdExtListDto dtoIdExtList) {
        // 组装 List
        List<Long> idList = new ArrayList<Long>(dtoIdExtList.getDtoList().size());
        for (IdExtDto dtoIdExt : dtoIdExtList.getDtoList()) {
            idList.add(Long.parseLong(dtoIdExt.getIdExt()));
        }
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModel model = new HelloWorldModel();
        model.setActive((short) 1);
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andIdIn(idList);
        // 执行数据库写操作，按 ID 列表删除
        int opResult = helloWorldModelMapper.updateByExampleSelective(model, example);
        log.debug("reviveBatch_by_id_list: " + idList + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto editSelective(@Valid HelloWorldP1K1Dto dtoP1K1) {
        // 使用 ModelMapper 工具将 DTO 转换成 Model
        HelloWorldModel model = modelMapper.map(dtoP1K1, HelloWorldModel.class);
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andUuidEqualTo(dtoP1K1.getUuid());
        // 执行数据库写操作
        int opResult = helloWorldModelMapper.updateByExampleSelective(model, example);
        log.debug("editSelective_dto: " + dtoP1K1.toString() + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public OpResultDto updateSelective(@Valid HelloWorldP1K2Dto dtoP1K2) {
        // 使用 ModelMapper 工具将 DTO 转换成 Model
        HelloWorldModel model = modelMapper.map(dtoP1K2, HelloWorldModel.class);
        Long id = Long.parseLong(dtoP1K2.getIdExt());
        model.setId(id);
        // 执行数据库写操作
        int opResult = helloWorldModelMapper.updateByPrimaryKeySelective(model);
        log.debug("updateSelective_dto: " + dtoP1K2.toString() + " opResult: " + opResult);
        // 组装 DTO 响应结构体
        OpResultDto dtoOpResult = OpResultDto.builder().opResult(opResult).build();
        return dtoOpResult;
    }

    @Override
    public CountResultDto getCount() {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 复杂的 where 条件
        criteria.andActiveEqualTo((short) 1);
        // 执行数据库读操作
        long countResult = helloWorldModelMapper.countByExample(example);
        // 组装 DTO 响应结构体
        CountResultDto dtoCountResult = CountResultDto.builder().countResult(Long.valueOf(countResult)).build();
        log.debug("getCount_size: " + dtoCountResult.getCountResult());
        return dtoCountResult;
    }

    @Override
    public HelloWorldR1K1Dto getOne(@Valid UuidDto dtoUuid) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 复杂的 where 条件
        criteria.andUuidEqualTo(dtoUuid.getUuid()).andActiveEqualTo((short) 1);
        // 执行数据库读操作，按 UUID 查询
        List<HelloWorldModel> modelList = helloWorldModelMapper.selectByExample(example);
        // 有可能查询不到，或者 active 为 1
        if (modelList.size() == 0) {
            log.warn("getOne_by_uuid: " + dtoUuid.getUuid() + " model: " + modelList.size());
            return null;
        }
        // 这里不可能发生，仅作示例，因为 UUID 标为 Unique Key
        if (modelList.size() > 1) {
            log.warn("getOne_by_uuid: " + dtoUuid.getUuid() + " model: " + modelList.size());
        }
        // 使用 ModelMapper 工具将 Model 转换成 Dto
        HelloWorldR1K1Dto dtoR1K1 = modelMapper.map(modelList.get(0), HelloWorldR1K1Dto.class);
        // DTO 中使用 Long 类型时间，手动转换
        dtoR1K1.setCreateTimeExt(modelList.get(0).getCreateTime().getTime());
        log.debug("getOne_by_uuid: " + dtoUuid.getUuid() + " model: " + modelList.size());
        return dtoR1K1;
    }

    @Override
    public HelloWorldR1K1ListDto getBatch(@Valid UuidListDto dtoUuidList) {
        // 组装 List
        List<String> uuidList = new ArrayList<String>(dtoUuidList.getDtoList().size());
        for (UuidDto dtoUuid : dtoUuidList.getDtoList()) {
            uuidList.add(dtoUuid.getUuid());
        }
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andUuidIn(uuidList).andActiveEqualTo((short) 1);
        example.setOrderByClause("id asc");
        // 执行数据库读操作，按 UUID 列表查询
        List<HelloWorldModel> modelList = helloWorldModelMapper.selectByExample(example);
        // 组装 DTO 响应结构体
        HelloWorldR1K1ListDto dtoR1K1List = HelloWorldR1K1ListDto.builder()
                .dtoList(new ArrayList<HelloWorldR1K1Dto>(modelList.size())).build();
        for (HelloWorldModel model : modelList) {
            // 使用 ModelMapper 工具将 Model 转换成 Dto
            HelloWorldR1K1Dto dtoR1K1 = modelMapper.map(model, HelloWorldR1K1Dto.class);
            // DTO 中使用 Long 类型时间，手动转换
            dtoR1K1.setCreateTimeExt(model.getCreateTime().getTime());
            dtoR1K1List.getDtoList().add(dtoR1K1);
        }
        log.debug("getBatch_by_uuid_list: " + uuidList + " dtoList.size: " + dtoR1K1List.getDtoList().size());
        return dtoR1K1List;
    }

    @Override
    public HelloWorldR1K1ListDto getByPage(@Valid PageRequestDto dtoPageRequest) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andActiveEqualTo((short) 1);
        // 利用 setOrderByClause 方法注入 limit 条件
        int page = dtoPageRequest.getPage();
        int limit = dtoPageRequest.getLimit();
        example.setOrderByClause("id asc limit " + (page * limit) + "," + limit);
        // 执行数据库读操作，分页查询
        List<HelloWorldModel> modelList = helloWorldModelMapper.selectByExample(example);
        // 组装 DTO 响应结构体
        HelloWorldR1K1ListDto dtoR1K1List = HelloWorldR1K1ListDto.builder()
                .dtoList(new ArrayList<HelloWorldR1K1Dto>(modelList.size())).build();
        for (HelloWorldModel model : modelList) {
            // 使用 ModelMapper 工具将 Model 转换成 Dto
            HelloWorldR1K1Dto dtoR1K1 = modelMapper.map(model, HelloWorldR1K1Dto.class);
            // DTO 中使用 Long 类型时间，手动转换
            dtoR1K1.setCreateTimeExt(model.getCreateTime().getTime());
            dtoR1K1List.getDtoList().add(dtoR1K1);
        }
        log.debug("getByPage_page: " + dtoPageRequest.getPage() + " limit: " + dtoPageRequest.getLimit()
                + " dtoList.size: "
                + dtoR1K1List.getDtoList().size());
        return dtoR1K1List;
    }

    @Override
    public UuidListDto getUuidByPage(@Valid PageRequestDto dtoPageRequest) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andActiveEqualTo((short) 1);
        // 利用 setOrderByClause 方法注入 limit 条件
        int page = dtoPageRequest.getPage();
        int limit = dtoPageRequest.getLimit();
        example.setOrderByClause("id asc limit " + (page * limit) + "," + limit);
        // 执行数据库读操作，分页查询，只返回 UUID，不带其它字段
        List<UuidDto> modelList = helloWorldModelMapper.selectUuidByExample(example);
        // 组装 DTO 响应结构体
        UuidListDto dtoUuidList = UuidListDto.builder()
                .dtoList(new ArrayList<UuidDto>(modelList.size())).build();
        for (UuidDto dtoUuid : modelList) {
            dtoUuidList.getDtoList().add(dtoUuid);
        }
        log.debug("getUuidByPage_page: " + dtoPageRequest.getPage() + " limit: " + dtoPageRequest.getLimit()
                + " dtoList.size: "
                + dtoUuidList.getDtoList().size());
        return dtoUuidList;
    }

    @Override
    public CountResultDto selectCount() {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        // 执行数据库读操作
        long countResult = helloWorldModelMapper.countByExample(example);
        // 组装 DTO 响应结构体
        CountResultDto dtoCountResult = CountResultDto.builder().countResult(Long.valueOf(countResult)).build();
        log.debug("selectCount_size: " + dtoCountResult.getCountResult());
        return dtoCountResult;
    }

    @Override
    public CountResultDto selectCountRemoved() {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andActiveEqualTo((short) 0);
        // 执行数据库读操作
        long countResult = helloWorldModelMapper.countByExample(example);
        // 组装 DTO 响应结构体
        CountResultDto dtoCountResult = CountResultDto.builder().countResult(Long.valueOf(countResult)).build();
        log.debug("selectCountRemoved_size: " + dtoCountResult.getCountResult());
        return dtoCountResult;
    }

    @Override
    public HelloWorldR1K2Dto selectOne(@Valid IdExtDto dtoIdExt) {
        Long id = Long.parseLong(dtoIdExt.getIdExt());
        // 执行数据库读操作
        HelloWorldModel model = helloWorldModelMapper.selectByPrimaryKey(id);
        if (model == null) {
            log.warn("selectOne_by_id: " + id + " model: 0");
            return null;
        }
        // 使用 ModelMapper 工具将 Model 转换成 Dto
        HelloWorldR1K2Dto dtoR1K2 = modelMapper.map(model, HelloWorldR1K2Dto.class);
        // DTO 中使用 String 类型 ID，手动转换
        dtoR1K2.setIdExt(model.getId().toString());
        // DTO 中使用 Long 类型时间，手动转换
        dtoR1K2.setCreateTimeExt(model.getCreateTime().getTime());
        log.debug("selectOne_by_id: " + id + " model: 1");
        return dtoR1K2;
    }

    @Override
    public HelloWorldR1K2ListDto selectBatch(@Valid IdExtListDto dtoIdExtList) {
        // 组装 List
        List<Long> idList = new ArrayList<Long>(dtoIdExtList.getDtoList().size());
        for (IdExtDto dtoIdExt : dtoIdExtList.getDtoList()) {
            idList.add(Long.parseLong(dtoIdExt.getIdExt()));
        }
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andIdIn(idList);
        example.setOrderByClause("id asc");
        // 执行数据库读操作，按 ID 列表查询
        List<HelloWorldModel> modelList = helloWorldModelMapper.selectByExample(example);
        // 组装 DTO 响应结构体
        HelloWorldR1K2ListDto dtoR1K2List = HelloWorldR1K2ListDto.builder()
                .dtoList(new ArrayList<HelloWorldR1K2Dto>(modelList.size())).build();
        for (HelloWorldModel model : modelList) {
            // 使用 ModelMapper 工具将 Model 转换成 Dto
            HelloWorldR1K2Dto dtoR1K2 = modelMapper.map(model, HelloWorldR1K2Dto.class);
            // DTO 中使用 String 类型 ID，手动转换
            dtoR1K2.setIdExt(model.getId().toString());
            // DTO 中使用 Long 类型时间，手动转换
            dtoR1K2.setCreateTimeExt(model.getCreateTime().getTime());
            dtoR1K2List.getDtoList().add(dtoR1K2);
        }
        log.debug("selectBatch_by_id_list: " + idList + " dtoList.size: "
                + dtoR1K2List.getDtoList().size());
        return dtoR1K2List;
    }

    @Override
    public HelloWorldR1K2ListDto selectByPage(@Valid PageRequestDto dtoPageRequest) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        // 利用 setOrderByClause 方法注入 limit 条件
        int page = dtoPageRequest.getPage();
        int limit = dtoPageRequest.getLimit();
        example.setOrderByClause("id asc limit " + (page * limit) + "," + limit);
        // 执行数据库读操作，分页查询
        List<HelloWorldModel> modelList = helloWorldModelMapper.selectByExample(example);
        // 组装 DTO 响应结构体
        HelloWorldR1K2ListDto dtoR1K2List = HelloWorldR1K2ListDto.builder()
                .dtoList(new ArrayList<HelloWorldR1K2Dto>(modelList.size())).build();
        for (HelloWorldModel model : modelList) {
            // 使用 ModelMapper 工具将 Model 转换成 Dto
            HelloWorldR1K2Dto dtoR1K2 = modelMapper.map(model, HelloWorldR1K2Dto.class);
            // DTO 中使用 String 类型 ID，手动转换
            dtoR1K2.setIdExt(model.getId().toString());
            // DTO 中使用 Long 类型时间，手动转换
            dtoR1K2.setCreateTimeExt(model.getCreateTime().getTime());
            dtoR1K2List.getDtoList().add(dtoR1K2);
        }
        log.debug("selectByPage_page: " + dtoPageRequest.getPage() + " limit: " + dtoPageRequest.getLimit()
                + " dtoList.size: "
                + dtoR1K2List.getDtoList().size());
        return dtoR1K2List;
    }

    @Override
    public IdExtListDto selectIdExtByPage(@Valid PageRequestDto dtoPageRequest) {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        // 利用 setOrderByClause 方法注入 limit 条件
        int page = dtoPageRequest.getPage();
        int limit = dtoPageRequest.getLimit();
        example.setOrderByClause("id asc limit " + (page * limit) + "," + limit);
        // 执行数据库读操作，分页查询，只返回 ID，不带其它字段
        List<Map<String, Long>> modelList = helloWorldModelMapper.selectIdExtByExample(example);
        // 组装 DTO 响应结构体
        IdExtListDto dtoIdExtList = IdExtListDto.builder()
                .dtoList(new ArrayList<IdExtDto>(modelList.size())).build();
        for (Map<String, Long> modelMap : modelList) {
            IdExtDto dtoIdExt = IdExtDto.builder().idExt(modelMap.get("id").toString())
                    .build();
            dtoIdExtList.getDtoList().add(dtoIdExt);
        }
        log.debug("selectIdExtByPage_page: " + dtoPageRequest.getPage() + " limit: " + dtoPageRequest.getLimit()
                + " dtoList.size: "
                + dtoIdExtList.getDtoList().size());
        return dtoIdExtList;
    }

    @Override
    public IdExtListDto selectIdExtRemoved() {
        // 使用 Model/Example/Criteria 构造查询条件
        HelloWorldModelExample example = new HelloWorldModelExample();
        Criteria criteria = example.createCriteria();
        // 使用 Criteria 类构建 where 条件
        criteria.andActiveEqualTo((short) 0);
        // 注入 OrderBy 条件
        example.setOrderByClause("id asc");
        // 执行数据库读操作
        List<Map<String, Long>> modelList = helloWorldModelMapper.selectIdExtByExample(example);
        // 组装 DTO 响应结构体
        IdExtListDto dtoIdExtList = IdExtListDto.builder()
                .dtoList(new ArrayList<IdExtDto>(modelList.size())).build();
        for (Map<String, Long> modelMap : modelList) {
            IdExtDto dtoIdExt = IdExtDto.builder().idExt(modelMap.get("id").toString())
                    .build();
            dtoIdExtList.getDtoList().add(dtoIdExt);
        }
        log.debug("selectIdExtRemoved_dtoList.size: " + dtoIdExtList.getDtoList().size());
        return dtoIdExtList;
    }

}